<template lang="pug">
  el-form(
    label-position="top"
    ref="form"
    :size="size"
    :model="formData"
    :colon="true"
    :label-width="isFilter ? 'auto' : labelWidth"
    :inline="isInlineForm"
    v-bind="formProps"
  style="padding:0;"
    )
    slot(name="front")
    template(v-if="isInlineForm")
      span(v-for="(item, index) in effectTotalItems" :key="item.key")
        //- slot
        el-form-item(:label="item.label" v-model="formData[item.key]" :prop="item.key" :rules="item.rules || []" v-if="!item.hidden && item.type === 'slot'")
          slot(:name="'form-' + item.key" v-bind="item")
        form-item(
          v-else
          v-model="formData[item.key]"
          :isFilter="isFilter"
          :formData="formData"
          :hidden="item.hidden"
          :prop="item.key"
          v-bind="item"
          @inputProps="inputProps"
        )
      el-form-item(v-if="showBtns")
        el-button.gradientVertical(:size="size" @click="submitForm" :loading="submitting" round) {{isFilter ? '查询' : (sureText || '保存')}}
    el-row(:gutter="16" v-else)
      el-col(
        v-for="(item, index) in effectTotalItems"
        :key="item.key"
        v-bind="item.layoutCol || layoutCol"
      )
        //- slot
        el-form-item(:label="item.label" v-model="formData[item.key]" :prop="item.key" :rules="item.rules || []" v-if="!item.hidden && item.type === 'slot'")
          slot(:name="'form-' + item.key" v-bind="item")
        form-item(
          v-else
          v-model="formData[item.key]"
          :isFilter="isFilter"
          :formData="formData"
          :hidden="item.hidden"
          :prop="item.key"
          v-bind="item"
          @inputProps="inputProps($event,item.flag || false)"
        )
      slot(name="otherItems")
      el-col(:span="24" :class="btnClass" v-if="showBtns")
        el-button(:size="size" v-if="reset || isFilter" :loading="submitting" :disabled="sureDisabled" @click="resetForm" round) 重置
        el-button(:size="size" v-if="!isFilter && showCancel" @click="cancelHandle" round) {{cancelText}}
        el-button.gradientVertical(:size="size" @click="submitForm" :loading="submitting" round) {{isFilter ? '查询' : (sureText || '保存')}}
</template>
<script>
import dayjs from 'dayjs'
import { isFunction } from '@/utils/types'
import { fileFormat } from '@/utils/util'
import FormItem from './FormItem'

const layoutCol = {
  sm: 12,
  md: 8,
  lg: 6
}

export default {
  name: 'FormBox',
  components: {
    FormItem
  },
  provide () {
    return {
      form: this
    }
  },
  props: {
    size: {
      type: String,
      default: 'default'
    },
    formProps: {
      type: Object,
      default: () => ({})
    },
    btnClass: {
      type: String,
      default: 'tr'
    },
    labelWidth: {
      type: String,
      default: '100px'
    },
    // 是否是表格搜索表单
    isFilter: Boolean,
    showCancel: {
      type: Boolean,
      default: true
    },
    showBtns: {
      type: Boolean,
      default: true
    },
    // 是否显示重置按钮
    reset: Boolean,
    // 是否显示取消按钮， 主要用于弹窗表单
    disabled: Boolean,
    cancelText: {
      type: String,
      default: '返回'
    },
    // 确认按钮文字
    sureText: {
      type: String,
      default: '保存'
    },
    layoutCol: {
      type: Object,
      default: () => {
        return layoutCol
      }
    },
    // 对外暴露submitting属性，用于显示提交按钮的loading状态
    submitting: {
      type: Boolean,
      default: false
    },
    // 表单列表
    fields: {
      type: [Array, Function],
      default: () => []
    },
    baseData: {
      type: Object,
      default: () => ({})
    },
    submitHandle: {
      type: Function,
      default: null
    }
  },
  data () {
    return {
      formData: {},
      initialForm: null,
      rules: {},
      sureDisabled: false
    }
  },
  computed: {
    isInlineForm () {
      return this.formProps.inline ?? this.isFilter
    },
    effectTotalItems () {
      const { fields, baseData } = this
      const items = (isFunction(fields) ? fields({ baseData }) : fields).filter(
        (item) => !item.hidden
      )
      return items
    }
  },
  watch: {
    fields: {
      handler (val) {
        const { baseData } = this
        if (isFunction(val)) {
          val = val({ baseData })
        }
        const form = {}
        const rules = {}
        // this.formData = {}
        val.forEach((item) => {
          // 获取校验规则
          if (item.rules) {
            rules[item.key] = item.rules
          }
          // 获取初始值
          if (item.value != null) {
            form[item.key] = item.value
          } else if (item.initialValue != null) {
            form[item.key] = item.initialValue
          } else if (item.type && !item.slot) {
            if (
              item.type.includes('range') ||
              item.type === 'upload' ||
              item.type === 'upload' ||
              item.mutiple
            ) {
              form[item.key] = this.formData[item.key] || []
            } else {
              switch (item.type) {
                case 'checkbox':
                case 'cascader':
                case 'transfer':
                case 'upload':
                case 'area':
                  form[item.key] = this.formData[item.key] || []
                  break
                case 'switch':
                  form[item.key] = this.formData[item.key] || false
                  break
                default:
                  form[item.key] = this.formData[item.key] || ''
              }
            }
          } else {
            form[item.key] = this.formData[item.key] || ''
          }
        })
        this.formData = form
        this.rules = rules
        this.initialForm = !this.initialForm ? { ...form } : this.initialForm
      },
      immediate: true,
      deep: true
    }
  },
  mounted () {},
  methods: {
    submitForm (e) {
      const { formData, effectTotalItems } = this
      e && e.preventDefault && e.preventDefault()
      return new Promise((resolve) => {
        this.$refs.form.validate((valid) => {
          if (valid) {
            console.log(formData)
            const formTemp = {}
            for (const item of effectTotalItems) {
              formTemp[item.key] = formData[item.key]
              // 是否时间格式化
              if (
                (item.formatFlag || this.isFilter) &&
                item.type &&
                (item.type.includes('date') || item.type.includes('time')) &&
                formData[item.key] &&
                !item.type.includes('updateImg')
              ) {
                const formatStr =
                  item.formatStr ||
                  (item.type.includes('time')
                    ? 'YYYY/MM/DD HH:mm:ss'
                    : 'YYYY/MM/DD')
                if (
                  item.type.includes('range') ||
                  (item.fieldProps && item.fieldProps['is-range'])
                ) {
                  if (formData[item.key].length > 0) {
                    formTemp[item.key1 ? item.key1 : `begin${item.key}`] =
                      dayjs(new Date(formData[item.key][0])).format(formatStr)
                    formTemp[item.key2 ? item.key2 : `end${item.key}`] = dayjs(
                      new Date(formData[item.key][1])
                    ).format(formatStr)
                  }
                  delete formTemp[item.key]
                } else {
                  formTemp[item.key] = dayjs(
                    new Date(formData[item.key])
                  ).format(formatStr)
                }
              }
              // 上传文件格式化文件
              if (
                item.type === 'upload' &&
                formData[item.key] &&
                Array.isArray(formData[item.key]) &&
                item.fieldProps?.autoUpload !== false
              ) {
                formTemp[item.key] = fileFormat(formData[item.key])
                // formData[item.key].map(file => {
                //   if (file.response && file.response.code === $successCode) {
                //     formTemp[item.key].push({
                //       name: file.name,
                //       url: file.response.data.url,
                //       type: file.raw?.type || ''
                //     })
                //   } else if (file.name) {
                //     formTemp[item.key].push({
                //       name: file.name,
                //       url: file.url
                //     })
                //   }
                // })
              }
            }
            // 提交表单
            if (this.submitHandle) {
              this.submitHandle(formTemp)
            }
            resolve(formTemp)
          } else {
            console.log('error submit!!')
            this.$message.error('请正确输入表单项')
            return false
          }
        })
      })
    },
    // 重置表单
    resetForm () {
      this.formData = { ...this.initialForm }
      if (this.searchHandle) {
        this.searchHandle(this.formData)
      }
    },
    cancelHandle () {
      this.$refs.form.resetFields()
      this.$refs.form.clearValidate()
      this.$emit('cancelHandle')
    },

    // 输入框事件
    inputProps (e, flag) {
      if (!flag) return
      this.$emit('inputChange', e)
    }
  }
}
</script>
<style lang="scss" scoped>
// .filterBtns{
//   padding-top: 3px;
//   box-sizing: border-box;
// }

.el-col-24 {
  &.filterBtns {
    padding-top: 0;
  }
}
</style>
